using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// using an alias here to make the Zing runtime references stand out more clearly
using Z = Microsoft.Zing;

[assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]		
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyDelaySign(false)]
[assembly: CLSCompliant(false)]
[assembly: ComVisible(false)]

// NOTE:
// Names of the form "userXXXX" refer to types or variables declared in the Zing
// source code, to help distinguish these from names generated by the compiler
// itself or those built into the Zing runtime code.


namespace Microsoft.Zing    // NOTE: namespace is fixed
{
    public class Application : Z.StateImpl      // NOTE: top-level class name is fixed
    {
        // for each user-defined interface, emit a corresponding class here.
        internal abstract class Interface : Z.ZingClass
        {
            public interface CreateMethods
            {
                // for each declared method InterfaceMethod, introduce the following declaration
                // public abstract InterfaceMethod CreateInterfaceMethod(Application application);
            }
        }

        internal abstract class InterfaceExtras : Z.ZingClass
        {
            public abstract __InterfaceMethod __CreateInterfaceMethod(Application application);
        }

        // for each user-defined class, emit a corresponding class here.
        internal class Class : Z.ZingClass
        {
            public Class(Application application) : base(application)
            {
                // For each non-static field with an initializer:
                //     Insert assignment statement to initialize the field here
            }
            public Class()
            {
            }

			private Class(Class c) : base(c)
			{
			}

            protected override short TypeId { get { return Class.typeId; } }
            private static readonly short typeId = 1;

            public override void WriteString(StateImpl state, BinaryWriter bw)
            {
                bw.Write(this.TypeId);

                // For each non-static field:
                //     Insert statement template "WriteSimpleField" or "WriteComplexField"
            }

			public override void TraverseFields(FieldTraverser ft)
			{
				ft.DoTraversal(this.TypeId);

				// For each non-static field:
				//     Insert statement template "WriteSimpleField" or "WriteComplexField"
			}
			
			public override object Clone()
            {
                Class newObj = new Class(this);
	
                cloneFields: ;
                    // For each non-static field:
                    //     Insert statement template "CloneField"

                return newObj;
            }

			public override object GetValue(int fi)
			{

			}

			public override void SetValue(int fi, object val)
			{

			}

            // For each non-static field:
            //     Insert field declaration here
        }

        internal class ClassExtras : Z.ZingClass
        {
            public override __InterfaceMethod __CreateInterfaceMethod(Application application)
            {
                return new __ClassMethod(application);
            }
        }

        #region Classes for user-defined methods

        // For each user-defined interface method:
        //     emit a class of the following form

        [Z.Activate]
        internal abstract class InterfaceMethod : Z.ZingMethod
        {
            public sealed class InputVars : UndoableStorage
            {
                internal ZingMethod stackFrame;
                internal InputVars(ZingMethod zm)
                {
                    stackFrame = zm;
                }

                public override UndoableStorage MakeInstance()
                {
                    return new InputVars(stackFrame);
                }

                public override void CopyContents(UndoableStorage usSrc)
                {
                    InputVars src = usSrc as InputVars;

                    if (src == null)
                        throw new ArgumentException("expecting instance of InputVars as source");

                    // ...
                }

                public override object GetValue(int fi)
                {
                }

                public override void SetValue(int fi, object val)
                {
                }

                public void WriteString(StateImpl state, BinaryWriter bw)
                {
                    // Emit a bw.Write() call for each member
                }

                public void TraverseFields(FieldTraverser ft)
                {
                    // Emit a ft.DoTraversal() call for each member
                }

                // For each input parameter to the method:
                //     emit a declaration here
            }

            public sealed class OutputVars : UndoableStorage
            {
                private ZingMethod stackFrame;
                internal OutputVars(ZingMethod zm)
                {
                    stackFrame = zm;
                }

                public override UndoableStorage MakeInstance()
                {
                    return new OutputVars(stackFrame);
                }

                public override void CopyContents(UndoableStorage usSrc)
                {
                    OutputVars src = usSrc as OutputVars;

                    if (src == null)
                        throw new ArgumentException("expecting instance of OutputVars as source");

                    // ...
                }

                public override object GetValue(int fi)
                {
                }

                public override void SetValue(int fi, object val)
                {
                }

                public void WriteString(StateImpl state, BinaryWriter bw)
                {
                    // Emit a bw.Write() call for each member
                }

                public void TraverseFields(FieldTraverser ft)
                {
                    // Emit a ft.DoTraversal() call for each member
                }

                // For each output parameter:
                //    emit a declaration here
                // If return type is not "void":
                //    emit a declaration here (name = "_ReturnValue")
            }

            public InputVars inputs;
            public OutputVars outputs;

            public override UndoableStorage Inputs { get { return inputs; } }
            public override UndoableStorage Outputs { get { return outputs; } }
        }

        // For each user-defined class method that implements and interface method:
        //     emit a class of the following form

        [Z.Activate]
        internal sealed class ClassMethod : __Method
        {
            // the splicer assumes that this is the first method in
            // the class
            public ClassMethod(Application app)
            {
                application = app;
                nextBlock = Blocks.Enter;
                handlerBlock = Blocks.None;
                locals = new LocalVars(this);
                inputs = new InputVars(this);
                outputs = new OutputVars(this);
            }

            private Application application;

            public override StateImpl StateImpl
            {
                get { return (StateImpl)application; }
                set { application = (Application)value; }
            }

            public sealed class LocalVars : UndoableStorage
            {
                private ZingMethod stackFrame;
                internal LocalVars(ZingMethod zm)
                {
                    stackFrame = zm;
                }

                public override UndoableStorage MakeInstance()
                {
                    return new LocalVars(stackFrame);
                }

                public override void CopyContents(UndoableStorage usSrc)
                {
                    LocalVars src = usSrc as LocalVars;

                    if (src == null)
                        throw new ArgumentException("expecting instance of LocalVars as source");

                    // ...
                }

                public override object GetValue(int fi)
                {
                }

                public override void SetValue(int fi, object val)
                {
                }

                public void WriteString(StateImpl state, BinaryWriter bw)
                {
                    // Emit a bw.Write() call for each member
                }

                public void TraverseFields(FieldTraverser ft)
                {
                    // Emit a ft.DoTraversal() call for each member
                }

                // For each local variable in the method:
                //     emit a member declaration here
            }

            public enum Blocks : ushort
            {
                None,
                Enter,
                // For each additional block:
                //     emit an additional enum member - B0, B1, ...
            };

            public LocalVars locals;

            public override UndoableStorage Locals { get { return locals; } }

            public override ushort NextBlock
            {
                get { return (ushort)nextBlock; }
                set { nextBlock = (Blocks)value; }
            }

            public override void WriteOutputsString(StateImpl state, BinaryWriter bw)
            {
                outputs.WriteString(state, bw);
            }

            public override string ProgramCounter
            {
                get { return nextBlock.ToString(); }
            }

            #region Undoable nextBlock and handlerBlock
            // for backwards compatibility...
            private Blocks privNextBlock, privHandlerBlock;

            // ULE for next block, handler block
            private class OthersULE
            {
                public bool nextBlockChanged;
                public bool handlerBlockChanged;
                public Blocks savedNextBlock;
                public Blocks savedHandlerBlock;

                public bool IsDirty
                {
                    get
                    {
                        return nextBlockChanged || handlerBlockChanged;
                    }
                }

                public OthersULE()
                {
                    nextBlockChanged = false;
                    handlerBlockChanged = false;
                }
            }

            OthersULE othersULE = null;

            // TODO: this should probably be public too but it currently breaks the browser
            private Blocks nextBlock
            {
                get { return privNextBlock; }
                set
                {
                    if (othersULE != null && !othersULE.nextBlockChanged)
                    {
                        othersULE.nextBlockChanged = true;
                        othersULE.savedNextBlock = privNextBlock;
                    }
                    privNextBlock = value;
                }
            }

            public Blocks handlerBlock
            {
                get { return privHandlerBlock; }
                set
                {
                    if (othersULE != null && !othersULE.handlerBlockChanged)
                    {
                        othersULE.handlerBlockChanged = true;
                        othersULE.savedHandlerBlock = privHandlerBlock;
                    }
                    privHandlerBlock = value;
                }
            }

            public override object DoCheckInOthers()
            {
                OthersULE res;

                if (othersULE == null)
                {
                    othersULE = new OthersULE();
                    return null;
                }

                if (!othersULE.IsDirty)
                    return null;

                res = othersULE;
                othersULE = new OthersULE();
                return res;
            }

            public override void DoRevertOthers()
            {
                Debug.Assert(othersULE != null);

                if (othersULE.nextBlockChanged)
                {
                    privNextBlock = othersULE.savedNextBlock;
                    othersULE.nextBlockChanged = false;
                }
                if (othersULE.handlerBlockChanged)
                {
                    privHandlerBlock = othersULE.savedHandlerBlock;
                    othersULE.handlerBlockChanged = false;
                }
            }

            public override void DoRollbackOthers(object[] ules)
            {
                Debug.Assert(othersULE != null);
                Debug.Assert(!othersULE.IsDirty);
                for (int i = 0, n = ules.Length; i < n; i++)
                {
                    if (ules[i] == null)
                        continue;
                    OthersULE ule = (OthersULE)ules[i];
                    if (ule.nextBlockChanged)
                        privNextBlock = ule.savedNextBlock;
                    if (ule.handlerBlockChanged)
                        privHandlerBlock = ule.savedHandlerBlock;
                }
            }
            #endregion

            public override bool RaiseZingException(int exception)
            {
                if (handlerBlock == Blocks.None)
                    return false;

                this.CurrentException = exception;
                nextBlock = handlerBlock;
                return true;
            }

            public override void Dispatch(Z.Process p)
            {
                switch (nextBlock)
                {
                    case Blocks.Enter: Enter(p); break;

                    // For each additional block:
                    //     emit an additional case as above...

                    default: throw new ApplicationException();
                }
            }

            public override ulong GetRunnableJoinStatements(Process p)
            {
                switch (nextBlock)
                {
                    // For each block that begins with a "select":
                    //     emit a case with an appropriate expression

                    default: return ~(ulong)0;
                }
            }

            public override bool IsAtomicEntryBlock()
            {
                switch (nextBlock)
                {
                    // For each block that increments atomicityLevel:
                    //     emit a case that returns true

                    default: return false;
                }
            }

            public override bool ValidEndState
            {
                get
                {
                    switch (nextBlock)
                    {
                        // For each block that begins with a "select" which
                        // is marked with with the "end" keyword, emit a
                        // case that returns true;

                        default: return false;
                    }
                }
            }

            //
            // For each block, we associate a source context. The context specifies the
            // source-level statement(s) contained in the block.
            //
            public override Z.ZingSourceContext Context
            {
                get
                {
                    switch (nextBlock)
                    {
                        // For each block:
                        //     emit a statement of the following form
                        //
                        // case Blocks.Bn: return new Z.ZingSourceContext(0, 0, 0);

                        default: throw new ApplicationException();
                    }
                }
            }

            public override Z.ZingAttribute ContextAttribute
            {
                get
                {
                    switch (nextBlock)
                    {
                        default: return null;
                    }
                }
            }

            #region Comparison

            public override int CompareTo(object obj)
            {
                //UserMethod other = (UserMethod) obj;

                // Compare this stack frame with another of the same type. This would
                // be used as a last resort to sort the process list if all cheaper
                // means of comparison indicate equality.

                // for each member of LocalVars, InputVars, and OutputVars, emit a comparison
                // of the following form:
                //
                // if (this.LocalVars.field1 < other.LocalVars.field1)
                //     return -1;
                // else if (this.LocalVars.field1 > other.LocalVars.field1)
                //     return 1;
                // else if (proceed to compare other fields)
                //     ...
                // else
                //     return 0;
                //
                //
                // NOTE: We compare simple field types first. Next, we would start
                // comparing fields within user-defined structs, if present. We
                // ignore pointers here for now on the assumption that the cost is
                // greater than the benefit at that point.

                return 0;
            }

            // Methods get a typeid too so that their stack frames are distinct
            private static readonly short typeId = 1;

            #endregion
        }

        internal class ThisField : Z.ZingMethod
        {
            public Z.Pointer privThis;
        }

        internal class StaticMethodExtras : Z.ZingMethod 
        {
            // This method is always emitted exactly as shown here. It can't be done in
            // the base class, however, because the definitions of locals, inputs, and
            // outputs are scoped to this class.
            public override ZingMethod Clone(Z.StateImpl myState, Z.Process myProcess, bool shallowCopy)
            {
                ClassMethod clone = new ClassMethod((Application) myState);

                clone.locals = new LocalVars(clone);
                clone.locals.CopyContents(locals);

                clone.inputs = new InputVars(clone);
                clone.inputs.CopyContents(inputs);

                clone.outputs = new OutputVars(clone);
                clone.outputs.CopyContents(outputs);

                clone.nextBlock = this.nextBlock;
                clone.handlerBlock = this.handlerBlock;
                // clone.application = (Application) myState;
                clone.SavedAtomicityLevel = this.SavedAtomicityLevel;

                if (this.Caller != null)
                {
					if(shallowCopy)
					{
						clone.Caller = null;
					}
					else
					{
						// Recursively clone the next frame in the stack
						clone.Caller = this.Caller.Clone(myState, myProcess, false);
					}
				}
                else
                {
                    // When we reach the entry point, patch our process appropriately
                    if (myProcess != null)
                        myProcess.EntryPoint = this;
                }

                return clone;
            }

            public override void WriteString(StateImpl state, BinaryWriter bw)
            {
                bw.Write(typeId);
                bw.Write((ushort) nextBlock);

                // Emit a bw.Write() call for each member of locals, inputs, and outputs.
                // For struct types, emit a call to their WriteString method.
                inputs.WriteString(state, bw);
                outputs.WriteString(state, bw);
                locals.WriteString(state, bw);
            }

			public override void TraverseFields(FieldTraverser ft)
			{
				ft.DoTraversal(typeId);
				ft.DoTraversal(nextBlock);

				// emit for each member of locals, inputs and outputs
                inputs.TraverseFields(ft);
                outputs.TraverseFields(ft);
                locals.TraverseFields(ft);
			}
		}

        internal class InstanceMethodExtras : Z.ZingMethod 
        {
            public override ZingMethod Clone(Z.StateImpl myState, Z.Process myProcess, bool shallowCopy)
            {
                ClassMethod clone = new ClassMethod((Application) myState);

                clone.locals = new LocalVars(clone);
                clone.locals.CopyContents(locals);

                clone.inputs = new InputVars(clone);
                clone.inputs.CopyContents(inputs);

                clone.outputs = new OutputVars(clone);
                clone.outputs.CopyContents(outputs);

                clone.nextBlock = this.nextBlock;
                clone.handlerBlock = this.handlerBlock;
                // clone.application = (Application) myState;
                clone.SavedAtomicityLevel = this.SavedAtomicityLevel;
                clone.privThis = this.privThis;

                if (this.Caller != null)
                {
					if(shallowCopy)
					{
						clone.Caller = null;
					}
					else
					{
						// Recursively clone the next frame in the stack
						clone.Caller = this.Caller.Clone(myState, myProcess, false);
					}
                }
                else
                {
                    // When we reach the entry point, patch our process appropriately
                    if (myProcess != null)
                        myProcess.EntryPoint = this;
                }

                return clone;
            }
            
            public override void WriteString(StateImpl state, BinaryWriter bw)
            {
                bw.Write(typeId);
                bw.Write((ushort) nextBlock);
                bw.Write(state.GetCanonicalId(privThis));

                // Emit a bw.Write() call for each member of locals, inputs, and outputs.
                // For struct types, emit a call to their WriteString method.
                inputs.WriteString(state, bw);
                outputs.WriteString(state, bw);
                locals.WriteString(state, bw);
            }

			public override void TraverseFields(FieldTraverser ft)
			{
				ft.DoTraversal(typeId);
				ft.DoTraversal(nextBlock);
				ft.DoTraversal(privThis);

				// emit for each member of locals, inputs and outputs
                inputs.TraverseFields(ft);
                outputs.TraverseFields(ft);
                locals.TraverseFields(ft);
			}
		}

        // For each block within a user-defined method:
        //     emit a method of the form shown by BlockMethod.B0
        public class BlockMethod
        {
            public void B0(Z.Process p)
            {
            }
        }

        // For each scope containing one or more pointer variables
        //     emit a method to "finalize" its local variables
        internal class ScopeMethod
        {
            public void Scope0()
            {
            }
        }

        public class BooleanReturnValueProperty
        {
            public override bool BooleanReturnValue
            {
                get { return outputs._ReturnValue; }
            }
        }

        #endregion

        internal class Enum
        {
            // for each user-defined enum type:
            //     emit a corresponding enum definition here

            //private enum UserEnumType { userEnumValue1, userEnumValue2, userEnumValue3 };

            // if the type appears as an argument to "choose" then emit a choose helper
            private static object[] _EnumTypeChoices = new object[] { };
        }

        internal class Range
        {
            // for each user-defined range type:
            //     emit a corresponding enum here

            internal enum _RangeType
            {
                Min = _MinValue,    // the minimum value for this range
                Max = _MaxValue,    // the maximum value for this range
            };

            // if the range appears as an argument to "choose", then emit a choose helper
            public static object[] _RangeTypeChoices = new object[] { };
        }

        // Static helper method for type-based "choose" operations
        internal class ChoiceHelper
        {
            public static object[] GetChoicesForType(System.Type type)
            {
                // Insert statement template <ChoiceHelperBody> here. String multiple
                // of these together - one per range or enum type.

                // Insert statement template <ChoiceHelperEnd> on the "else" clause of
                // the last statement above
            }
        }


        internal struct Struct
        {
            // for each user-defined struct, emit a corresponding struct definition here

            public void WriteString(StateImpl state, BinaryWriter bw)
            {
            }
			public void TraverseFields(FieldTraverser ft)
			{
			}

        }
     
        #region Sets

        sealed internal class SimpleSet : Z.ZingSet
        {
            public SimpleSet(Application app): base(app) { }
            public SimpleSet() { }
			private SimpleSet(SimpleSet c) : base(c) { }
            protected override short TypeId { get { return SimpleSet.typeId; } }
            private static readonly short typeId = 1;

            public override Type ElementType { get { return typeof(_ElementType); } }

            public _ElementType this[int index]
            {
                get { return (_ElementType) base.GetItem(index);  }
            }

            public override object Clone()
            {
                SimpleSet newObj = new SimpleSet(this);

                foreach (_ElementType v in this.ArrayList)
                    newObj.ArrayList.Add(v);

                return newObj;
            }

            public override void WriteString(StateImpl state, BinaryWriter bw)
            {
                bw.Write(this.TypeId);
                bw.Write(this.Count);

                this.ArrayList.Sort();

                foreach (_ElementType x in this.ArrayList)
                    bw.Write(x);
            }
			public override void TraverseFields(FieldTraverser ft)
			{
				ft.DoTraversal(this.TypeId);
				ft.DoTraversal(this.Count);
				foreach (_ElementType x in this.ArrayList)
					ft.DoTraversal(x);
			}
		}

        sealed internal class EnumSet : Z.ZingSet
        {
            public EnumSet(Application app): base(app) { }
            public EnumSet() { }
			private EnumSet(EnumSet c) : base(c) { }
            protected override short TypeId { get { return EnumSet.typeId; } }
            private static readonly short typeId = 1;

            public override Type ElementType { get { return typeof(_ElementType); } }

            public _ElementType this[int index]
            {
                get { return (_ElementType) base.GetItem(index);  }
            }

            public override object Clone()
            {
                EnumSet newObj = new EnumSet(this);

                foreach (_ElementType v in this.ArrayList)
                    newObj.ArrayList.Add(v);

                return newObj;
            }

            public override void WriteString(StateImpl state, BinaryWriter bw)
            {
                bw.Write(this.TypeId);
                bw.Write(this.Count);

                this.ArrayList.Sort();

                foreach (_ElementType x in this.ArrayList)
                    bw.Write((byte) x);
            }

			public override void TraverseFields(FieldTraverser ft)
			{
				ft.DoTraversal(this.TypeId);
				ft.DoTraversal(this.Count);
				foreach (_ElementType x in this.ArrayList)
					ft.DoTraversal(x);
			}
		}

        sealed internal class StructSet : Z.ZingSet
        {
            public StructSet(Application app) : base(app) { }
            public StructSet() { }
			private StructSet(StructSet c) : base(c) { }
            protected override short TypeId { get { return StructSet.typeId; } }
            private static readonly short typeId = 1;

            public override Type ElementType { get { return typeof(_ElementType); } }

            public _ElementType this[int index]
            {
                get { return (_ElementType) base.GetItem(index);  }
            }

            public override object Clone()
            {
                StructSet newObj = new StructSet(this);

                foreach (_ElementType v in this.ArrayList)
                    newObj.ArrayList.Add(v);

                return newObj;
            }

            public override void WriteString(StateImpl state, BinaryWriter bw)
            {
                bw.Write(this.TypeId);
                bw.Write(this.Count);

                foreach (_ElementType x in this.ArrayList)
                    x.WriteString(state, bw);
            }

			public override void TraverseFields(FieldTraverser ft)
			{
				ft.DoTraversal(this.TypeId);
				ft.DoTraversal(this.Count);
				foreach (_ElementType x in this.ArrayList)
					x.TraverseFields(ft);
					//ft.DoTraversal(x);
			}
		}

        sealed internal class ComplexSet : Z.ZingSet
        {
            public ComplexSet(Application app) : base(app) { }
            public ComplexSet() { }
			private ComplexSet(ComplexSet c) : base(c) { }
            protected override short TypeId { get { return ComplexSet.typeId; } }
            private static readonly short typeId = 1;

            public override Type ElementType { get { return typeof(_ElementType); } }

            public Z.Pointer this[int index]
            {
                get { return (Z.Pointer) base.GetItem(index);  }
            }

            public override object Clone()
            {
                ComplexSet newObj = new ComplexSet(this);

                foreach (Z.Pointer ptr in this.ArrayList)
                    newObj.ArrayList.Add(ptr);

                return newObj;
            }
		}

        #endregion

        #region Arrays

        sealed internal class SimpleArray : Z.ZingArray
        {
            public _ElementType[] array;

            public SimpleArray(Application app, int size) : base(app) 
            {
				 array = new _ElementType[size];
            }

            public SimpleArray(int size)
            {
                array = new _ElementType[size];
            }

			private SimpleArray(SimpleArray c) : base(c)
			{
				array = new _ElementType[c.Count];
			}

            protected override Array Array { get { return array; } }

            protected override short TypeId { get { return SimpleArray.typeId; } }
            private static readonly short typeId = 1;

            public override Type ElementType { get { return typeof(_ElementType); } }

            public override object Clone()
            {
                SimpleArray newObj = new SimpleArray(this);
                array.CopyTo(newObj.array, 0);
                return newObj;
            }

            public _ElementType this[int index]
            {
                get { 
					_ElementType t = array[index];
					return t;  
				}
                set { 
					SetDirty(); 
					array[index] = value; 
				}
            }

            public override void WriteString(StateImpl state, BinaryWriter bw)
            {
                bw.Write(this.TypeId);
                bw.Write(this.Count);

                foreach (_ElementType x in array)
                    bw.Write(x);
            }

			public override void TraverseFields(FieldTraverser ft)
			{
				ft.DoTraversal(this.TypeId);
				ft.DoTraversal(this.Count);
				foreach (_ElementType x in array)
					ft.DoTraversal(x);
			}

			public override object GetValue(int fi) 
			{
				return array[fi];
			}

			public override void SetValue(int fi, object val)
			{
				array[fi] = (_ElementType) val;
			}
        }

        sealed internal class EnumArray : Z.ZingArray
        {
            public _ElementType[] array;

            public EnumArray(Application app, int size) : base(app) 
            {
				array = new _ElementType[size]; 
            }

            public EnumArray(int size)
            {
                array = new _ElementType[size];
            }

			private EnumArray(EnumArray c) : base(c)
			{
				array = new _ElementType[c.Count];
			}

            protected override Array Array { get { return array; } }

            protected override short TypeId { get { return EnumArray.typeId; } }
            private static readonly short typeId = 1;

            public override Type ElementType { get { return typeof(_ElementType); } }

            public override object Clone()
            {
                EnumArray newObj = new EnumArray(this);
                array.CopyTo(newObj.array, 0);
                return newObj;
            }

            public _ElementType this[int index]
            {
                get { 
					_ElementType t = array[index];
					return t;  
				}
                set { 
					SetDirty(); 
					array[index] = value; 
				}
            }

            public override void WriteString(StateImpl state, BinaryWriter bw)
            {
                bw.Write(this.TypeId);
                bw.Write(this.Count);

                foreach (_ElementType x in array)
                    bw.Write((byte)x);
            }

			public override void TraverseFields(FieldTraverser ft)
			{
				ft.DoTraversal(this.TypeId);
				ft.DoTraversal(this.Count);
				foreach (_ElementType x in array)
					ft.DoTraversal(x);
			}
			
			public override object GetValue(int fi) 
			{
				return array[fi];
			}

			public override void SetValue(int fi, object val)
			{
				array[fi] = (_ElementType) val;
			}
        }

        sealed internal class StructArray : Z.ZingArray
        {
            public _ElementType[] array;

            public StructArray(Application app, int size) : base(app)
            {
				 array = new _ElementType[size];
            }

            public StructArray(int size)
            {
                array = new _ElementType[size];
            }

			private StructArray(StructArray c) : base(c)
			{
				array = new _ElementType[c.Count];
			}

            protected override Array Array { get { return array; } }

            protected override short TypeId { get { return StructArray.typeId; } }
            private static readonly short typeId = 1;

            public override Type ElementType { get { return typeof(_ElementType); } }

            public override object Clone()
            {
                StructArray newObj = new StructArray(this);
                // clone the elements of the array?
                array.CopyTo(newObj.array, 0);
                return newObj;
            }

            public _ElementType this[int index]
            {
				get { 
					_ElementType t = array[index];
					return t;  
				}
				set { 
					SetDirty(); 
					array[index] = value; 
				}
            }

            public override void WriteString(StateImpl state, BinaryWriter bw)
            {
                bw.Write(this.TypeId);
                bw.Write(this.Count);

                foreach (_ElementType x in array)
                    x.WriteString(state, bw);
            }
			public override void TraverseFields(FieldTraverser ft)
			{
				ft.DoTraversal(this.TypeId);
				ft.DoTraversal(this.Count);
				foreach (_ElementType x in array)
					x.TraverseFields(ft);
					//ft.DoTraversal(x);
			}
			
			public override object GetValue(int fi) 
			{
				return array[fi];
			}

			public override void SetValue(int fi, object val)
			{
				array[fi] = (_ElementType) val;
			}
        }

        sealed internal class ComplexArray : Z.ZingArray
        {
            public Z.Pointer[] array;

            public ComplexArray(Application app, int size) : base(app)
            {
				 array = new Z.Pointer[size];
            }

            public ComplexArray(int size)
            {
                array = new Z.Pointer[size];
            }

			private ComplexArray(ComplexArray c) : base(c)
			{
				array = new Z.Pointer[c.Count];
			}

            protected override Array Array { get { return array; } }

            protected override short TypeId { get { return ComplexArray.typeId; } }
            private static readonly short typeId = 1;

            public override Type ElementType { get { return typeof(_ElementType); } }

            public override object Clone()
            {
                ComplexArray newObj = new ComplexArray(this);
                array.CopyTo(newObj.array, 0);
                return newObj;
            }

            public Z.Pointer this[int index]
            {
				get 
				{ 
					Z.Pointer t = array[index];
					return t;  
				}
				set 
				{ 
					SetDirty(); 
					array[index] = value; 
				}                
			}
			
			public override object GetValue(int fi) 
			{
				return array[fi];
			}

			public override void SetValue(int fi, object val)
			{
				array[fi] = (Z.Pointer) val;
			}
        }

        #endregion

        #region Channels

        sealed internal class SimpleChan : Z.ZingChan
        {
            public SimpleChan(Application app) : base(app) { }
            public SimpleChan() { }
			private SimpleChan(SimpleChan c) : base(c) { }
            protected override short TypeId { get { return SimpleChan.typeId; } }
            private static readonly short typeId = 1;

            public override Type MessageType { get { return typeof(_ElementType); } }

            public override object Clone()
            {
                SimpleChan newObj = new SimpleChan(this);

                foreach (_ElementType v in this.Queue)
                    newObj.Queue.Enqueue(v);

                return newObj;
            }

            public override void WriteString(StateImpl state, BinaryWriter bw)
            {
                bw.Write(this.TypeId);
                bw.Write(this.Count);

                foreach (_ElementType x in this.Queue)
                    bw.Write(x);
            }
			public override void TraverseFields(FieldTraverser ft)
			{
				ft.DoTraversal(this.TypeId);
				ft.DoTraversal(this.Count);
				foreach (_ElementType x in this.Queue)
					ft.DoTraversal(x);
			}
		}

        sealed internal class EnumChan : Z.ZingChan
        {
            public EnumChan(Application app) : base(app){ }
            public EnumChan() { }
            private EnumChan(EnumChan c) : base(c) { }
			protected override short TypeId { get { return EnumChan.typeId; } }
            private static readonly short typeId = 1;

            public override Type MessageType { get { return typeof(_ElementType); } }

            public override object Clone()
            {
                EnumChan newObj = new EnumChan(this);

                foreach (_ElementType v in this.Queue)
                    newObj.Queue.Enqueue(v);

                return newObj;
            }

            public override void WriteString(StateImpl state, BinaryWriter bw)
            {
                bw.Write(this.TypeId);
                bw.Write(this.Count);

                foreach (_ElementType x in this.Queue)
                    bw.Write((byte) x);
            }
			public override void TraverseFields(FieldTraverser ft)
			{
				ft.DoTraversal(this.TypeId);
				ft.DoTraversal(this.Count);
				foreach (_ElementType x in this.Queue)
					ft.DoTraversal(x);
			}
		}

        sealed internal class StructChan : Z.ZingChan
        {
            public StructChan(Application app): base(app) { }
            public StructChan() { }
			private StructChan(StructChan c) : base(c) { }
            protected override short TypeId { get { return StructChan.typeId; } }
            private static readonly short typeId = 1;

            public override Type MessageType { get { return typeof(_ElementType); } }

            public override object Clone()
            {
                StructChan newObj = new StructChan(this);

                foreach (_ElementType v in this.Queue)
                    newObj.Queue.Enqueue(v);    // clone the elements of the queue?

                return newObj;
            }

            public override void WriteString(StateImpl state, BinaryWriter bw)
            {
                bw.Write(this.TypeId);
                bw.Write(this.Count);

                foreach (_ElementType x in this.Queue)
                    x.WriteString(state, bw);
            }
			public override void TraverseFields(FieldTraverser ft)
			{
				ft.DoTraversal(this.TypeId);
				ft.DoTraversal(this.Count);
				foreach (_ElementType x in this.Queue)
					x.TraverseFields(ft);
					//ft.DoTraversal(x);
			}
		}

        sealed internal class ComplexChan : Z.ZingChan
        {
            public ComplexChan(Application app): base(app) { }
            public ComplexChan() { }
			private ComplexChan(ComplexChan c) : base(c) { }
            protected override short TypeId { get { return ComplexChan.typeId; } }
            private static readonly short typeId = 1;

            public override Type MessageType { get { return typeof(_ElementType); } }

            public override object Clone()
            {
                ComplexChan newObj = new ComplexChan(this);

                foreach (Z.Pointer ptr in this.Queue)
                    newObj.Queue.Enqueue(ptr);

                return newObj;
            }
        }

        #endregion

    }
}
